package com.fangzhi.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fangzhi.mapper.AdminAccountRoleDeptRelationMapper;
import com.fangzhi.mobel.AdminAccountRoleDeptRelation;
import com.fangzhi.mobel.ProductType;
import com.fangzhi.mobel.enums.GlobalCodeEnum;
import com.fangzhi.mobel.io.SaveProductTypeIo;
import com.fangzhi.mobel.vo.PageVo;
import com.fangzhi.mobel.vo.ProductListByIdVo;
import com.fangzhi.mobel.vo.ProductListVo;
import com.fangzhi.mobel.vo.QueryProductDetailVo;
import com.fangzhi.service.ProductTypeService;
import com.fangzhi.mapper.ProductTypeMapper;
import com.fangzhi.utils.BeanCopyUtil;
import com.fangzhi.utils.GlobalParam;
import com.fangzhi.utils.ResponseResult;
import com.fasterxml.jackson.annotation.JsonInclude;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
* @author edy
* @description 针对表【product_type(类目表)】的数据库操作Service实现
* @createDate 2024-09-12 16:28:09
*/
@Service
public class ProductTypeServiceImpl extends ServiceImpl<ProductTypeMapper, ProductType>
    implements ProductTypeService{

    @Autowired
    private AdminAccountRoleDeptRelationMapper adminAccountRoleDeptRelationMapper;

    @Override
    public ResponseResult saveProductType(SaveProductTypeIo io) {
//        // 验证账号权限是否为超级管理员
//        Long id = GlobalParam.LOGIN_ACCOUNT_INFO.get().getId();
//        AdminAccountRoleDeptRelation adminAccountRoleDeptRelation = adminAccountRoleDeptRelationMapper
//                .selectOne(Wrappers.<AdminAccountRoleDeptRelation>lambdaQuery()
//                .eq(AdminAccountRoleDeptRelation::getAdminAccounntId, id)
//                .in(AdminAccountRoleDeptRelation::getRoleId, Arrays.asList(1, 2)));
//        if (null == adminAccountRoleDeptRelation)
//            return ResponseResult.systemException(GlobalCodeEnum.GL_FAIL_9997);

        // 查询可用否存在该分类
        ProductType productType = this.getBaseMapper().selectOne(Wrappers.<ProductType>lambdaQuery()
                .eq(ProductType::getParentId, io.getParentId())
                .eq(ProductType::getStatus, 1)
                .eq(ProductType::getProductName, io.getProductName()));
        if (null != productType)
            return ResponseResult.systemException(GlobalCodeEnum.GL_FAIL_9994);

        productType = BeanCopyUtil.copyProperties(io, ProductType.class);
        Integer level = this.queryLevelByParentId(io.getParentId());
        productType.setLevel(level);
        if (null != io.getPrice()){
            BigDecimal multiply = io.getPrice().multiply(BigDecimal.valueOf(100));
            productType.setPrice(multiply.intValue());
        }
        boolean save = this.save(productType);
        if (save)
            return ResponseResult.OK();
        throw new RuntimeException("添加规格失败" + JSON.toJSONString(io));
    }

    @Override
    public ResponseResult productList() {
        List<ProductType> productTypes = this.getBaseMapper().selectList(Wrappers.<ProductType>lambdaQuery().eq(ProductType::getStatus, 1));
        List<ProductListVo> productListVos = convertToListVo(productTypes);
        return ResponseResult.OK(productListVos);
    }

    @Override
    public ResponseResult productListById(Integer id, String name, Integer pageNo, Integer pageSize) {
        Long total =  this.getBaseMapper().selectCount(Wrappers.<ProductType>lambdaQuery()
                .eq(ProductType::getParentId, id)
                .like(ProductType::getProductName, name)
                .eq(ProductType::getStatus, 1));
        if (total == 0L)
            return ResponseResult.OK(new PageVo().setTotal(total).setData(new ArrayList<>()));

        List<ProductType> productTypes = this.getBaseMapper().selectList(Wrappers.<ProductType>lambdaQuery()
                .eq(ProductType::getParentId, id)
                .like(ProductType::getProductName, name)
                .eq(ProductType::getStatus, 1)
                .last(" limit " + (pageNo - 1) * pageSize + "," + pageSize));

        List<ProductListByIdVo> copy = productTypes.stream().map(T->{
            ProductType productType = this.getBaseMapper().selectById(T.getParentId());

            return new ProductListByIdVo().setId(T.getId()).setProductName(T.getProductName()).setParentId(T.getParentId())
                    .setParentName(productType.getProductName()).setImageCover(T.getImageCover()).setPrice(T.getPrice())
                    .setComments(T.getComments()).setProcureCount(T.getProcureCount()).setLevel(T.getLevel());
        }).collect(Collectors.toList());
        return ResponseResult.OK(new PageVo().setTotal(total).setData(copy));
    }

    @Override
    public ResponseResult removeProductType(Integer id) {
        ProductType productType = this.getBaseMapper().selectById(id);
        if (null == productType)
            return ResponseResult.systemException(GlobalCodeEnum.GL_FAIL_9996);
        if (productType.getParentId() == 0L)
            return ResponseResult.systemException(GlobalCodeEnum.GL_FAIL_9997);
        productType.setStatus(2);
        int i = this.getBaseMapper().updateById(productType);
        if (i == 1)
            return ResponseResult.OK();
        throw new RuntimeException("下线产品异常" + JSON.toJSONString(id));
    }

    @Override
    public String queryBaneById(Long productTypeId) {
        ProductType productType = this.getBaseMapper().selectById(productTypeId);
        StringBuilder sb = new StringBuilder();
        sb.append(productType.getProductName());
        productTypeId = productType.getParentId();
        while (productTypeId != 1L) {
            productType = this.getBaseMapper().selectById(productTypeId);
            sb.insert(0, productType.getProductName() + "|");
            productTypeId = productType.getParentId();
        }
        return sb.toString();
    }

    @Override
    public ResponseResult queryProductDetail(Integer id) {
        ProductType productType = this.getBaseMapper().selectById(id);
        if (productType.getLevel()< 4)
            return ResponseResult.OK();

        QueryProductDetailVo queryProductDetailVo = new QueryProductDetailVo();
        queryProductDetailVo.setId(productType.getId());
        queryProductDetailVo.setPrice(productType.getPrice() / 100D);
        StringBuilder sb = new StringBuilder();
        sb.append(productType.getProductName());

        Long parentId = productType.getParentId();
        do {
            productType = this.getBaseMapper().selectById(parentId);
            parentId = productType.getParentId();
            if (productType.getParentId() != 0)
                sb.insert(0, productType.getProductName() + "|");
        }while (parentId != 0);
        queryProductDetailVo.setProductName(sb.toString());
        return ResponseResult.OK(queryProductDetailVo);
    }

    @Override
    public ResponseResult updateProductType(SaveProductTypeIo io) {
        BigDecimal multiply = io.getPrice().multiply(BigDecimal.valueOf(100));
        ProductType byId = this.getById(io.getId());
        System.out.println(multiply.intValue());
        byId.setPrice(multiply.intValue()).setProductName(io.getProductName()).setComments(io.getComments());
        return ResponseResult.OK(updateById(byId));
    }


    public static List<ProductListVo> convertToListVo(List<ProductType> products) {
        Map<Long, ProductListVo> idToNodeMap = new HashMap<>();
        Map<Long, List<ProductListVo>> parentIdToNodeMap = new HashMap<>();
        for (ProductType product : products) {
            ProductListVo vo = new ProductListVo();
            vo.setId(product.getId());
            vo.setLevel(product.getLevel());
            vo.setLabel(product.getProductName());
            idToNodeMap.put(product.getId(), vo);

            if (product.getParentId() != null) {
                parentIdToNodeMap.computeIfAbsent(product.getParentId(), k -> new ArrayList<>()).add(vo);
            } else {
                parentIdToNodeMap.put(0L, new ArrayList<>());
                parentIdToNodeMap.get(0L).add(vo);
            }
        }
        for (ProductListVo vo : idToNodeMap.values()) {
            Long parentId = vo.getId(); // Use the current node's ID as the parent ID to find its children
            List<ProductListVo> children = parentIdToNodeMap.get(parentId);
            if (children != null) {
                vo.setChildren(children);
            } else {
                vo.setChildren(new ArrayList<>()); // No children, set an empty list to avoid null
            }
        }
        return parentIdToNodeMap.get(0L);
    }


    public Integer queryLevelByParentId(Long id){
        Integer level = 0;
        ProductType productType;
        do {
            level ++;
            productType = this.getBaseMapper().selectById(id);
            id = productType.getParentId();
        }while (productType.getParentId() != 0L);
        return level;
    }
}




